-
Notifications
You must be signed in to change notification settings - Fork 585
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Adding GpioPin #1895
Adding GpioPin #1895
Conversation
I was expecting this to be a draft PR, or a PR against a feature branch. What is the intention of this @Ellerbach? This would have to go through APIReview first before it can get merged. |
That's fine. I can mark the PR as Draft then. If you prefer, I can just push the branch directly to the repo so it will be its own feature branch. |
@joperezr can we do small API review during triage meeting? This API is not part of the framework and we didn't go through API review for other smaller things |
If the breaking change is acceptable for 3.0 and well documented, it's fine to wait for that version to be out. In the mean time, it does allow time to align on the design. |
I don't think this is a small thing to be honest. This was one of the biggest design decisions made on the original design, and I do think that getting this reviewed by more people would help as most of us are already a bit biased. |
Some notes (+ my after-thoughts) from the offline conversation between me and @Ellerbach today:
|
Few elements to take into consideration:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good overall. What's not so nice IMHO is that the code to keep the current state of the pin for the Toggle operation is duplicated all over the place.
Please also add a test case for this functionality.
I'll have to take a look whether the now valid duplicate open causes some problems in the pin management for the board. I don't expect so, as this should have triggered a test then.
/// Toggle the current value of a pin. | ||
/// </summary> | ||
/// <param name="pinNumber">The pin number in the driver's logical numbering scheme.</param> | ||
protected internal abstract void Toggle(int pinNumber); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's a real breaking change (binary as well as source). I think this should have a default implementation instead.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not PinValue Toggle(int pinNumber)
?
I don't know if the hw implementation provides the value, but in the other cases it is certainly available.
If the hardware driver does not provide the value, we can decide to either return null or read the value and return it.
I prefer this signature to avoid future breaking changes in case the hw driver will provide the value in the next releases.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's a real breaking change (binary as well as source). I think this should have a default implementation instead.
Some hardware provide this feature, so does not. We agreeded that the braking change is ok as it then surfaced on the GpioController following the API call. And the best way to handle the change is to move it to the driver because it's the only place tracking really the state of the pins.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great work @Ellerbach!
} | ||
|
||
[Fact] | ||
public void TestOpnPin() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Typo: TestOpenPin
in place of TestOpnPin
/// Toggle the current value of a pin. | ||
/// </summary> | ||
/// <param name="pinNumber">The pin number in the driver's logical numbering scheme.</param> | ||
protected internal abstract void Toggle(int pinNumber); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not PinValue Toggle(int pinNumber)
?
I don't know if the hw implementation provides the value, but in the other cases it is certainly available.
If the hardware driver does not provide the value, we can decide to either return null or read the value and return it.
I prefer this signature to avoid future breaking changes in case the hw driver will provide the value in the next releases.
Hardware does not provide. I know that for all current implementation we keep track, so could be provided but in real hardware, it's not. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
At this point I guess we can go on with this :)
We were discussing in the triage to shape the api as
@joperezr Do you have an opinion on this? |
src/System.Device.Gpio/System/Device/Gpio/Drivers/HummingBoardDriver.cs
Outdated
Show resolved
Hide resolved
private readonly ConcurrentDictionary<int, SafeLineHandle> _pinNumberToSafeLineHandle; | ||
private readonly ConcurrentDictionary<int, LibGpiodDriverEventHandler> _pinNumberToEventHandler; | ||
private readonly int _pinCount; | ||
private readonly ConcurrentDictionary<int, PinValue> _pinValue; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm looking at this and wondering - perhaps GpioDriver could have virtual CreateGpioPin
with default implementation - then in here you'd return LibGpiodPin
and move CurrentPinValue
, EventHandler
, SafeLineHandle
to LibGpiodPin
- this way you could have just one ConcurrentDictionary
here and using pin directly would have advantage of not touching ConcurrentDictionary
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we talked offline and we can do this as a separate change most likely without any API changes (only addition suggested here)
GpioPin pin = ctrl.OpenPin(PinNumber, PinMode.Input); | ||
// Assert | ||
Assert.True(pin.PinNumber == PinNumber); | ||
Assert.True(pin.GetPinMode() == PinMode.Input); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: Assert.Equal
@@ -14,6 +14,7 @@ public class Windows10Driver : GpioDriver | |||
{ | |||
private static readonly WinGpio.GpioController s_winGpioController = WinGpio.GpioController.GetDefault(); | |||
private readonly Dictionary<int, Windows10DriverPin> _openPins = new Dictionary<int, Windows10DriverPin>(); | |||
private readonly Dictionary<int, PinValue> _pinValues = new Dictionary<int, PinValue>(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why does LibGpiodDriver need ConcurrentDictionary while this one is ok with regular Dictionary?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(it's an existing issue anyway so don't worry about this in this PR)
// Simulate a key press | ||
Interop.keybd_event((byte)virtualKey, | ||
0x45, | ||
Interop.KEYEVENTF_EXTENDEDKEY | 0, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: | 0
is a nop so Interop.KEYEVENTF_EXTENDEDKEY | 0
is the same as Interop.KEYEVENTF_EXTENDEDKEY
@@ -519,12 +532,14 @@ private void ThrowBadPin(string argument) | |||
protected override void OpenPin(int pinNumber) | |||
{ | |||
// No-op | |||
_pinValues.TryAdd(pinNumber, PinValue.Low); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: comment above is no longer true
@@ -161,6 +161,8 @@ protected override PinValue Read(int pinNumber) | |||
return PinValue.Low; | |||
} | |||
|
|||
protected override void Toggle(int pinNumber) => Write(pinNumber, !Read(pinNumber)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can be removed given current virtual implementation
} | ||
|
||
/// <inheritdoc/> | ||
protected override void Toggle(int pinNumber) => Write(pinNumber, !_pinValues[pinNumber]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure dictionary actually makes it faster for those low level drivers - reading/writing pin is supposedely fastest operation you can make if you think about it. It might be currently faster this way because of OS but in principal that shouldn't be the case
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should measure this later on. Also some drivers do not support reading when mode is output.
@@ -65,6 +65,8 @@ protected override PinValue Read(int pinNumber) | |||
return _hardwareLevelAccess.ReadPin(pinNumber); | |||
} | |||
|
|||
protected override void Toggle(int pinNumber) => Write(pinNumber, !Read(pinNumber)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: can be removed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM with couple of nits. feel free to ignore or fix separately
* Adding GpioPin * adjusting based on PR feedback * Adjusting to have natively drivers. * make methods virtual * adding Toggle to System.Device drivers * Board and Mcp23xxx adjustments * adding FT4222, FT232H and Pcx857x * adding Arduino and Seasaw * adjsting file encoding after conflict merge * Adding missing Toggle implementation in Arduino native * Adjusting test for new pattern with GpioPin * adjusting PR feedback * typo in test * fixing nit * fixing test * fixing test
* Add IS31FL3731 LED matrix binding * Update sample * Make program more generic * Add specific bindings * Add Phat 17x7 binding * Add Phat 17x7 binding * Add LED Shim 28x1 driver * Update switch expression * Update TPN * Add README * Add Led Matrix Breakout 11x7 binding * Update README for led matrix breakout * Add Led RGB Matrix 5x5 binding * Add 5x5 RGB Matrix sample * Switch integers to decimals * Fix syntax * Rename type * Update per feedback * Update per feedback * Switch to enums for const data * Switch from enum to static class * Switch to ROS * Fix flipped field * Update brightness * Update TFMs * Adding GpioPin (#1895) * Adding GpioPin * adjusting based on PR feedback * Adjusting to have natively drivers. * make methods virtual * adding Toggle to System.Device drivers * Board and Mcp23xxx adjustments * adding FT4222, FT232H and Pcx857x * adding Arduino and Seasaw * adjsting file encoding after conflict merge * Adding missing Toggle implementation in Arduino native * Adjusting test for new pattern with GpioPin * adjusting PR feedback * typo in test * fixing nit * fixing test * fixing test * Bump Microsoft.CodeAnalysis.CSharp.Scripting in /tools/DevicesApiTester (#1981) Bumps [Microsoft.CodeAnalysis.CSharp.Scripting](https://github.com/dotnet/roslyn) from 4.3.1 to 4.4.0. - [Release notes](https://github.com/dotnet/roslyn/releases) - [Changelog](https://github.com/dotnet/roslyn/blob/main/docs/Breaking%20API%20Changes.md) - [Commits](https://github.com/dotnet/roslyn/commits/Visual-Studio-2019-Version-16.0-Preview-4.4) --- updated-dependencies: - dependency-name: Microsoft.CodeAnalysis.CSharp.Scripting dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Bump Microsoft.Net.Compilers.Toolset in /tools/DevicesApiTester (#1980) Bumps [Microsoft.Net.Compilers.Toolset](https://github.com/dotnet/roslyn) from 4.3.1 to 4.4.0. - [Release notes](https://github.com/dotnet/roslyn/releases) - [Changelog](https://github.com/dotnet/roslyn/blob/main/docs/Breaking%20API%20Changes.md) - [Commits](https://github.com/dotnet/roslyn/commits/Visual-Studio-2019-Version-16.0-Preview-4.4) --- updated-dependencies: - dependency-name: Microsoft.Net.Compilers.Toolset dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Upgrade to .NET 7 GA (#1988) * Upgrade to .NET 7 GA * Update global.json Co-authored-by: Jose Perez Rodriguez <joperezr@microsoft.com> * Update blinking * Add 'Port of' comments * Update sample * Update sample * Update comment * Update per feedback * Add 'Port of' comment * Move samples to directories * Update README * Change exception type Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: Laurent Ellerbach <laurelle@microsoft.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Jose Perez Rodriguez <joperezr@microsoft.com>
Adding GpioPin. Following design discussions here: #1671
This PR now implements what's been discussed during the API proposal call and is summarized here: #1920
Microsoft Reviewers: Open in CodeFlow